<?php
/**
 * 客户crm
 * Created by PhpStorm.
 * User: 万奇
 * Date: 2020/11/29 0029
 * Time: 23:15
 */

namespace app\admin\model;


use app\core\Wechat;
use think\facade\Db;

class WxkCustomer extends BasicModel
{
    public function __construct(array $data = [])
    {
        parent::__construct($data);
    }

    /**
     * 回显编辑客户画像
     * User: 万奇
     * Date: 2021/4/30 0024
     * @return mixed
     */
    public function show_edit_customer_portrait()
    {
        //获取全行业
        $industry           = Db::name('sys_category')->where('is_del', 0)->field('id,pid,name')->select()->toArray();

        $industry_groping   = array_grouping($industry, 'pid');
        $result['industry'] = $industry_groping ? category_group($industry_groping, $industry_groping[0], 'children', 'id') : [];
        $result['follow']   = \StaticData::RESOURCE_NAME['follow_status'];

        return $result;
    }

    /**
     * 获取客户画像
     * User: 万奇
     * Date: 2021/4/28 0024
     * @param $param
     * @return array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function get_customer_portrait($param)
    {
        $result = Db::name('wxk_customer_portrait')->where(['external_user_id' => $param['external_user_id']])->find();

        return $result ? $result : [];
    }

    /**
     * 编辑客户操作记录
     * User: 万奇
     * Date: 2021/3/25 0025
     * @param $param
     * @param $user_id
     * @param $user_type
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit_customer_action_log($param, $user_id, $user_type)
    {
        $customer_info = $this->field('follow_remark_mobiles,follow_remark')->where(['external_user_id' => $param['external_user_id'], 'follow_userid' => $param['follow_userid']])->find()->toArray();
        $portrait      = Db::name('wxk_customer_portrait')->where(['external_user_id' => $param['external_user_id']])->find();
        $customer_info = array_merge($customer_info, $portrait ? $portrait : []);

        $filed = [
            'follow_remark_mobiles' => '手机号', 'follow_remark' => '备注', 'name' => '姓名', 'intention' => '客户意向', 'gender' => '性别',
            'email'                 => '邮箱', 'age' => '年龄', 'industry' => '行业', 'birthday' => '生日', 'area' => '区域', 'qq' => 'QQ', 'hobby' => '爱好',
            'wechat'                => '微信号', 'income' => '年收入', 'follow_remark_company' => '公司', 'address' => '地址', 'photo' => '画像', 'photo_txt' => '画像描述'
        ];

        $user_name = get_operator_name($user_id, $user_type);
        $txt       = '';
        foreach ($filed as $k => $v) {
            if (!$portrait) {
                if (isset($param[$k])) {
                    $txt .= $txt ? '、' . $v : $user_name . ' 完善客户信息：' . $v;
                }
            } else {
                if (isset($param[$k]) && $param[$k] != $customer_info[$k]) {
                    $txt .= $txt ? '、' . $v : $user_name . ' 完善客户信息：' . $v;
                }
            }
        }

        if ($txt) {
            WxkCustomerTrack::add_customer_track($param['external_user_id'], $txt, 2);
        }
    }

    /**
     * 修改客户详情
     * User: 万奇
     * Date: 2021/3/24 0024
     * @param $param
     * @param $add_user  - 操作人 user_id
     * @param $user_type 1-成员 2-系统人员
     * @throws \think\db\exception\DbException
     */
    public function edit_customer_info($param, $add_user, $user_type)
    {
        $data   = [];
        $update = [];
        $remark = false;

        if (isset($param['follow_remark_mobiles']) && !empty($param['follow_remark_mobiles'])) {
            $reg_phone = reg_phone($param['follow_remark_mobiles']);
            if (!$reg_phone) {
                response(500, '手机号码格式不正确');
            }
            $remark                          = true;
            $data['remark_mobiles']          = explode(',', $param['follow_remark_mobiles']);
            $update['follow_remark_mobiles'] = $param['follow_remark_mobiles'];
        }
        if (isset($param['follow_remark']) && !empty($param['follow_remark'])) {
            $remark                  = true;
            $data['remark']          = $param['follow_remark'];
            $update['follow_remark'] = $param['follow_remark'];
        }
        if (isset($param['follow_remark_company']) && !empty($param['follow_remark_company'])) {
            $remark                          = true;
            $data['remark_company']          = $param['follow_remark_company'];
            $update['follow_remark_company'] = $param['follow_remark_company'];
        }
        if ($remark) {
            // 更新企业微信客户信息
            $data['userid']          = $param['follow_userid'];
            $data['external_userid'] = $param['external_user_id'];
            $wechat                  = new Wechat();
            $url                     = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark';
            $remark                  = $wechat->request_wechat_api($url, 'wxk_customer_admin_secret', $data, true, true);

            if ($remark['errcode'] != 0) {
                response(500, $remark);
            }

            $this->where(['external_user_id' => $param['external_user_id'], 'follow_userid' => $param['follow_userid']])->update($update);
        }

        $is_portrait = Db::name('wxk_customer_portrait')->where(['external_user_id' => $param['external_user_id']])->count();

        // 客户互动轨迹
        $this->edit_customer_action_log($param, $add_user, $user_type);

        if ($is_portrait) {
            Db::name('wxk_customer_portrait')->where(['external_user_id' => $param['external_user_id']])->strict(false)->update($param);
        } else {
            Db::name('wxk_customer_portrait')->strict(false)->insert(array_merge(['id' => uuid()], $param));
        }
    }


    /**
     * 客户详情
     * User: 万奇
     * Date: 2021/3/23 0023
     * @param $param
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function get_customer_info($param)
    {
        // 移动端
        if (isset($param['is_api'])) {
            $param['id'] = $this->where(['external_user_id' => $param['external_user_id'], 'follow_userid' => $param['follow_userid']])->value('id');
            if (!$param['id']) {
                response(200, '暂无数据', []);
            }
        }

        $result   = $this->repeat_list_customer(['id' => $param['id'], 'limit' => 1])['data'][0];
        $portrait = Db::name('wxk_customer_portrait')->field('intention,area')->where(['id' => $result['external_user_id']])->find();

        $result['intention'] = isset($portrait['intention']) ? $portrait['intention'] : '';
        $result['area']      = isset($portrait['area']) ? $portrait['area'] : '';
        //        $result['group']    = Db::name('wxk_customer_group_member')->alias('a')
        //            ->join('wxk_customer_group b', 'a.group_id=b.id','left')
        //            ->where(['a.user_id' => $result['external_user_id']])
        //            ->group('b.id')
        //            ->column('b.id,b.name,b.owner_user_id');

        //        $group_model        = new WxkCustomerGroup();
        //        $result['group']    = $group_model->_get_customer_group_name($result['group'], $param['corp_id']);
        $result['deal_num'] = Db::name('wxk_customer_follow')->where(['external_user_id' => $result['external_user_id'], 'follow_userid' => $result['follow_userid'], 'follow_type' => 4])->count();

        return $result;
    }

    /**
     * 首页引流数据统计
     * User: 万奇
     * Date: 2021/1/23 0023
     * @return array
     */
    public function index_drainage_data()
    {
        $drainage_type  = \StaticData::RESOURCE_NAME['drainage_type'];
        $customer_total = $this->count();

        $result = [];
        foreach ($drainage_type as $k => $v) {
            $result[$k]['name'] = $v;
            switch ($k) {
                case 1 :
                    $result[$k]['count'] = $this->where([['follow_state', '<>', '']])->count();
                    break;
                case 7 :
                    $result[$k]['count'] = $customer_total - $result[1]['count'];
                    break;
                default :
                    $result[$k]['count'] = 0;
                    break;
            }
        }

        return array_values($result);
    }

    /**
     * 客户列表
     * User: 万奇
     * Date: 2020/12/3 0003
     * @param $param
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function get_list_customer($param)
    {
        $where = [];

        if (is_exists($param['keyword'])) {
            $where[] = ['name|follow_remark', 'like', "%{$param['keyword']}%"];
        }

        if (is_exists($param['gender'], false, true)) {
            $where[] = ['gender', '=', $param['gender']];
        }

        if (is_exists($param['follow_remark_mobiles'])) {
            $where[] = ['follow_remark_mobiles', 'like', "%{$param['follow_remark_mobiles']}%"];
        }

        if (is_exists($param['follow_add_way'], false, true)) {
            $where[] = ['follow_add_way', '=', $param['follow_add_way']];
        }

        if (is_exists($param['follow_status'])) {
            $where[] = ['follow_status', '=', $param['follow_status']];
        }

        if (is_exists($param['follow_userid'])) {
            $where[] = ['follow_userid', '=', $param['follow_userid']];
        }

        if (is_exists($param['start_time']) && is_exists($param['end_time'])) {
            $where[] = ['follow_createtime', 'between', [$param['start_time'], $param['end_time']]];
        }

        $list = $this->where($where)->order(['follow_createtime' => 'desc'])->paginate($param['limit'])->toArray();

        $staff    = Db::name('wxk_staff')->where([['user_id', 'in', implode(',', array_column($list['data'], 'follow_userid'))]])->column('name,department_id', 'user_id');
        $tag_name = Db::name('wxk_customer_tag')->column('name', 'id');
        $section  = Db::name('wxk_department')->column('code,name', 'code');

        $staff_model = new WxkStaff();
        foreach ($list['data'] as $k => $v) {
            $list['data'][$k]['tag_ids']             = get_name_attr($tag_name, $v['tag_ids']);
            $list['data'][$k]['follow_name']         = $staff[$v['follow_userid']]['name'];
            $list['data'][$k]['follow_section_name'] = $staff_model->section_attr($section, $staff[$v['follow_userid']]['department_id']);
            $list['data'][$k]['follow_add_way']      = $v['follow_add_way'] ? \StaticData::RESOURCE_NAME['follow_add_way'][$v['follow_add_way']] : \StaticData::RESOURCE_NAME['follow_add_way'][0];
            $list['data'][$k]['follow_status']       = Db::name('wxk_customer_follow')->where(['external_user_id' => $v['external_user_id'], 'follow_userid' => $v['follow_userid']])->order(['create_at' => 'desc'])->value('follow_type', 1);
            $list['data'][$k]['follow_status']       = \StaticData::RESOURCE_NAME['follow_status'][$list['data'][$k]['follow_status']];
        }

        return ['data' => $list['data'], 'count' => $list['total']];
    }

    /**
     * 客户打标签/移除标签
     * User: 万奇
     * Date: 2021/1/15 0015
     * @param $param
     * @param $uid       - 操作人 user_id
     * @param $user_type 1-系统人员 2-成员
     */
    public function customer_tagging($param, $uid, $user_type)
    {
        $wechat    = new Wechat();
        $url       = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag';
        $customer  = $this->where([['id', 'in', implode(',', $param['id'])]])->column('external_user_id,tag_ids,follow_userid', 'id');
        $tag_name  = Db::name('wxk_customer_tag')->column('name', 'id');
        $user_name = get_operator_name($uid, $user_type);

        if ($param['type'] == 1) {
            foreach ($customer as $k => $v) {
                $data     = ['userid' => $v['follow_userid'], 'external_userid' => $v['external_user_id'], 'add_tag' => $param['tag_ids']];

                $mark_tag = $wechat->request_wechat_api($url, 'wxk_customer_admin_secret', $data, true, true);

                if ($mark_tag['errcode'] != 0) {
                    response(500, '操作失败');
                }

                $update['tag_ids'] = implode(',', $v['tag_ids'] ? array_unique(array_merge(explode(',', $v['tag_ids']), $param['tag_ids'])) : $param['tag_ids']);
                $this->where(['id' => $k])->update($update);

                // 添加客户轨迹
                $tag_txt = [];
                foreach ($param['tag_ids'] as $t_k => $t_v) {
                    $tag_txt[$t_k] = $tag_name[$t_v];
                }

                $txt = "$user_name 对客户添加标签 : " . implode('、', $tag_txt);
                WxkCustomerTrack::add_customer_track($v['external_user_id'], $txt, 2);
            }
        } else {
            foreach ($customer as $k => $v) {
                $data     = ['userid' => $v['follow_userid'], 'external_userid' => $v['external_user_id'], 'remove_tag' => $param['tag_ids']];

                $mark_tag = $wechat->request_wechat_api($url, 'wxk_customer_admin_secret', $data, true, true);

                if ($mark_tag['errcode'] != 0) {
                    response(500, '操作失败');
                }

                $update['tag_ids'] = implode(',', array_diff(explode(',', $v['tag_ids']), $param['tag_ids']));
                $this->where(['id' => $k])->update($update);

                // 添加客户轨迹
                $tag_txt = [];
                foreach ($param['tag_ids'] as $t_k => $t_v) {
                    $tag_txt[$t_k] = $tag_name[$t_v];
                }

                $txt = "$user_name 对客户移除标签 : " . implode('、', $tag_txt);
                WxkCustomerTrack::add_customer_track($v['external_user_id'], $txt, 2);
            }
        }

    }

    /**
     * 客户打标签回显已有的标签
     * User: 万奇
     * Date: 2021/1/14 0014
     * @param $param
     * @return array
     */
    public function show_customer_tag($param)
    {
        $list = Db::name($param['table_name'])->where([['id', 'in', implode(',', $param['id'])], ['tag_ids', '<>', '']])->column('tag_ids');

        $result = [];
        if (!count($list)) {
            return $result;
        }
        if ($param['type'] == 1) {
            $list_count = array_count_values(explode(',', implode(',', $list)));

            foreach ($list_count as $k => $v) {
                if ($v >= count($list)) {
                    $result[] = $k;
                }
            }
        } else {
            $result = array_unique(explode(',', implode(',', $list)));
        }

        return $result;
    }

    /**
     * 重复客户列表
     * User: 万奇
     * Date: 2021/1/14 0014
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function repeat_list_customer($param)
    {
        $where = [];

        if (is_exists($param['id'])) {
            $where[] = ['id', '=', $param['id']];
        }

        if (is_exists($param['keyword'])) {
            $where[] = ['name|follow_remark', 'like', "%{$param['keyword']}%"];
        }

        if (is_exists($param['gender'], false, true)) {
            $where[] = ['gender', '=', $param['gender']];
        }

        if (is_exists($param['follow_userid'])) {
            $where[] = ['follow_userid', '=', $param['follow_userid']];
        }

        if (is_exists($param['start_time']) && is_exists($param['end_time'])) {
            $where[] = ['follow_createtime', 'between', [$param['start_time'], $param['end_time']]];
        }

        $list = $this->where($where)->order(['follow_createtime' => 'desc'])->group('external_user_id');
        $list = !empty($param['id']) ? $list->paginate($param['limit'])->toArray() : $list->having('count(external_user_id) > 1')->paginate($param['limit'])->toArray();

        $tag_name = Db::name('wxk_customer_tag')->column('name', 'id');
        $staff    = Db::name('wxk_staff')->column('name,department_id', 'user_id');
        $section  = Db::name('wxk_department')->column('code,name', 'code');

        $staff_model = new WxkStaff();
        foreach ($list['data'] as $k => $v) {
            $list['data'][$k]['follow_info'] = $this->field('tag_ids,follow_userid,follow_remark,follow_createtime')->where(['external_user_id' => $v['external_user_id']])->select()->toArray();
            foreach ($list['data'][$k]['follow_info'] as $f_k => $f_v) {
                $list['data'][$k]['follow_info'][$f_k]['follow_section_name'] = $staff_model->section_attr($section, $staff[$f_v['follow_userid']]['department_id']);
                $list['data'][$k]['follow_info'][$f_k]['follow_name']         = $staff[$f_v['follow_userid']]['name'];
            }
            $list['data'][$k]['follow_add_way'] = \StaticData::RESOURCE_NAME['follow_add_way'][$v['follow_add_way'] ?: 0];
            $list['data'][$k]['follow_status']  = Db::name('wxk_customer_follow')->where(['external_user_id' => $v['external_user_id'], 'follow_userid' => $v['follow_userid']])->order(['create_at' => 'desc'])->value('follow_type', 1);
            $list['data'][$k]['follow_status']  = \StaticData::RESOURCE_NAME['follow_status'][$list['data'][$k]['follow_status']];
            $list['data'][$k]['tag_ids']        = !empty($param['id']) ? get_name_attr($tag_name, $v['tag_ids']) : get_name_attr($tag_name, implode(',', array_filter(array_column($list['data'][$k]['follow_info'], 'tag_ids'))));
        }

        return ['data' => $list['data'], 'count' => $list['total']];
    }

    /**
     * 客户列表渲染
     * User: 万奇
     * Date: 2021/1/14 0014
     * @return mixed
     */
    public function show_list_customer()
    {
        $result['gender']         = \StaticData::RESOURCE_NAME['gender'];
        $result['follow_add_way'] = \StaticData::RESOURCE_NAME['follow_add_way'];
        $result['follow_status']  = \StaticData::RESOURCE_NAME['follow_status'];

        $result['all_num']    = $this->count();
        $result['actual_num'] = $this->group('external_user_id')->count();

        return $result;
    }

    /**
     * 企微客户批量同步
     * User: 万奇、臭臭羊
     * Date: 2021/4/16 0016
     * @throws \think\db\exception\DbException
     */
    public function synchro_customer()
    {
        $wechat        = new Wechat();
        $staff_user_id = Db::name('wxk_staff')->column('user_id');

        Db::name('wxk_customer')->delete(true);

        foreach ($staff_user_id as $k => $v) {
            $nextCursor = '';
            //如果还有后续可导入的客户 一直持续到客户不存在了
            do {
                $param = [
                    'userid' => $v,
                    'cursor' => $nextCursor,
                    'limit'  => 100,//默认一次取limit极限值
                ];

                $getClientInfoFirst = $wechat->get_client_all_info(['type' => 'wxk_customer_admin_secret'], $param);
                $list               = $getClientInfoFirst['external_contact_list'];
                $nextCursor         = $getClientInfoFirst['next_cursor'];

                $this->insert_customer($list, $param);

            } while ($nextCursor);
        }
    }

    /**
     * 执行企微客户的插入
     * User: 万奇
     * Date: 2021/4/16 0016
     * @param $list
     * @param $param
     */
    public function insert_customer($list, $param)
    {
        $data = [];
        if (count($list)) {
            foreach ($list as $i_k => $i_v) {
                if ($i_v['external_contact']['type'] == 1) {
                    $company_name = $i_v['follow_info']['remark_corp_name'] ?? '';
                } else {
                    $company_name = $i_v['external_contact']['corp_full_name'] ?? '';
                }
                $data[$i_k]['id']                    = uuid();
                $data[$i_k]['external_user_id']      = $i_v['external_contact']['external_userid'];
                $data[$i_k]['name']                  = $i_v['external_contact']['name'];
                $data[$i_k]['avatar']                = $i_v['external_contact']['avatar'];
                $data[$i_k]['customer_type']         = $i_v['external_contact']['type'];
                $data[$i_k]['gender']                = $i_v['external_contact']['gender'];
                $data[$i_k]['follow_remark_company'] = $company_name;
                $data[$i_k]['tag_ids']               = isset($i_v['follow_info']['tag_id']) ? implode(',', $i_v['follow_info']['tag_id']) : '';
                $data[$i_k]['follow_userid']         = $param['userid'];
                $data[$i_k]['follow_remark']         = $i_v['follow_info']['remark'];
                $data[$i_k]['follow_createtime']     = format_time($i_v['follow_info']['createtime']);
                $data[$i_k]['follow_remark_mobiles'] = count($i_v['follow_info']['remark_mobiles']) ? implode(',', $i_v['follow_info']['remark_mobiles']) : '';
                $data[$i_k]['follow_add_way']        = isset($i_v['follow_info']['add_way']) ? $i_v['follow_info']['add_way'] : '';
                $data[$i_k]['follow_oper_userid']    = isset($i_v['follow_info']['oper_userid']) ? $i_v['follow_info']['oper_userid'] : '';
                $data[$i_k]['follow_state']          = isset($i_v['follow_info']['state']) ? $i_v['follow_info']['state'] : '';
            }
            $this->insertAll($data);
        }
    }

}